"""
系统配置信息模块
"""

import copy

from app.dao import (Base, get_db_session, Column, String, INTEGER, TIMESTAMP, paginate)
from app.common.constants import (Switch, SysConfigConstants)
from app.dto.sysconfig import SysConfigDto
from app.utils.dateutil import get_current_time_str


class SysConfig(Base):
    """
    系统配置信息类
    """

    # 数据库表名
    __tablename__ = "sys_config"

    # 主键ID
    id = Column('id', INTEGER, primary_key=True, autoincrement=True)
    # 用户名称
    name = Column('name', String(32), nullable=False)
    # 标识
    nid = Column('nid', String(32), nullable=False)
    # 标识对应的值
    value = Column('value', String(128), nullable=False)
    # 类型
    type = Column('type', INTEGER, nullable=False)
    # 状态
    status = Column('status', INTEGER, nullable=False)
    # 备注
    remark = Column('remark', String(128), default='')
    # 添加时间
    add_time = Column('add_time', TIMESTAMP, nullable=False,
                      default=get_current_time_str())
    # 修改时间
    modify_time = Column('modify_time', TIMESTAMP)

    def __str__(self):
        return "({0.id!s}, {0.name!s}, {0.nid!s}, {0.value!s}, {0.type!s}, {0.status!s}, {0.remark!s})".format(
            self)


class SysConfigDao(object):
    """
    系统配置信息Dao类
    """

    @classmethod
    def save(cls, item):
        """
        保存
        :param item:
        :return:
        """
        with get_db_session() as session:
            obj = SysConfig(name=item.name, nid=item.nid, value=item.value, type=item.type,
                            status=item.status, remark=item.remark)
            session.add(obj)
            session.commit()
            return obj

    @classmethod
    def save_all(cls, item_list):
        """
        批量保存（使用SQLAlchemy Core进行性能优化，只需发送一条SQL）
        :param item_list:
        :return:
        """

        obj_list = []
        for item in item_list:
            obj = SysConfig(name=item.name, nid=item.nid, value=item.value, type=item.type,
                            status=item.status, remark=item.remark).__dict__
            obj_list.append(obj)

        with get_db_session() as session:
            session.execute(SysConfig.__table__.insert(), obj_list)
            session.commit()
        return obj_list

    @classmethod
    def remove_by_id(cls, id_):
        """
        根据id进行逻辑删除
        :param id_:
        :return:
        """
        with get_db_session() as session:
            result = session.query(SysConfig).filter_by(id=id_).update(dict(
                status=Switch.NO.value[0],
                modify_time=get_current_time_str()
            ))
            session.commit()

        return result

    @classmethod
    def update(cls, item):
        """
        更新
        :param item:
        :return:
        """
        with get_db_session() as session:
            session.commit()
            result = session.query(SysConfig).filter_by(id=item.id).update(dict(
                name=item.name,
                nid=item.nid,
                value=item.value,
                status=item.status,
                remark=item.remark,
                modify_time=get_current_time_str()
            ))

        return result

    @classmethod
    def find_by_id(cls, id_):
        """
        根据id获取
        :param id_:
        :return:
        """
        with get_db_session() as session:
            result = session.query(SysConfig).filter_by(id=id_).first()
            if result:
                return copy.deepcopy(result)

    @classmethod
    def find_by_nid_and_type_and_status(cls, nid, type_, status=Switch.YES.value[0]):
        """
        根据nid、type_、status获取
        :param nid:
        :param type_:
        :param status:
        :return:
        """
        filters = set()
        filters.add(SysConfig.nid == nid)
        filters.add(SysConfig.type == type_)
        filters.add(SysConfig.status == status)

        with get_db_session() as session:
            result = session.query(SysConfig).filter(*filters).first()
            if result:
                return copy.deepcopy(result)

    @classmethod
    def find_all(cls):
        """
        获取所有
        :return:
        """

        with get_db_session() as session:
            result = session.query(SysConfig).all()
            if result:
                # 需要使用深度拷贝
                return copy.deepcopy(result)

    @classmethod
    def page_by_param(cls, page=1, page_size=10, **kwargs):
        """
        分页查询
        :param page:
        :param page_size:
        :param kwargs:
        :return:
        """

        if page < 1:
            page = 1

        # 比filter_by的功能更强大，支持比较运算符，支持or、in_等语法。
        filters = set()

        if 'name' in kwargs:
            name = kwargs['name']
            if name:
                filters.add(SysConfig.name.ilike('%' + name + '%'))

        if 'nid' in kwargs:
            nid = kwargs['nid']
            if nid:
                filters.add(SysConfig.real_name.ilike('%' + nid + '%'))

        if 'type_' in kwargs:
            filters.add(SysConfig.type == kwargs['type_'])

        if 'status' in kwargs:
            filters.add(SysConfig.status == kwargs['status'])

        with get_db_session() as session:
            page_query = session.query(SysConfig).filter(*filters).order_by(
                SysConfig.status.asc(),
                SysConfig.type.asc(),
                SysConfig.id.desc())
            pagination = paginate(page_query, page=page, page_size=page_size)
            result = dict(
                items=copy.deepcopy(pagination.items),
                previous_page=pagination.previous_page,
                next_page=pagination.next_page,
                has_previous=pagination.has_previous,
                has_next=pagination.has_next,
                total=pagination.total,
                pages=pagination.pages,
                page=page,

            )

            return result


if __name__ == "__main__":
    # name = '静态图片服务器地址'
    # nid = 'image_server_url'
    # value = 'http://localhost:9000'
    # type_ = SysConfigConstants.Type.SYS.value[0]
    # remark = '静态图片服务器地址'

    # sys_config = SysConfigDto(name=name, nid=nid, value=value, type_=type_,
    #                           remark=remark)
    # SysConfigDao.save(sys_config)
    #
    # item = SysConfigDao.find_by_nid_and_type_and_status(nid=nid, type_=type_)
    # print(item)

    # item_list = SysConfigDao.find_all()
    # for item in item_list:
    #     print(item)

    # result = SysConfigDao.page_by_param(type_=type_, name=name)
    # result = SysConfigDao.page_by_param()
    # print(result)
    pass
